package com.example.service;

import com.alibaba.fastjson.JSON;
import com.example.dto.MessageDto;
import com.example.entity.Order;
import com.example.entity.OrderSort;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageDeliveryMode;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.BatchingRabbitTemplate;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@Service
@Slf4j
public class OrderService {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Resource
    private BatchingRabbitTemplate batchingRabbitTemplate;

//    @Resource
//    private BatchingRabbitTemplateFactory batchingRabbitTemplateFactory;

    // 发送订单创建消息
    public void createOrder(Order order) {
        log.info("接收到订单：{}", order);
        //版本1
        // 转换为JSON（推荐使用Jackson2JsonMessageConverter）
        rabbitTemplate.convertAndSend(
                "order.exchange",  // Exchange名称
                "order.create",    // Routing Key
                order              // 消息体
        );


    }

    public void createTryOrder(Order order) {
        log.info("接收到订单：{}", order);
        //版本2 添加确认监听
        // 生产者添加确认监听
        rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
            if (ack) {
                log.info("消息成功到达Broker，correlationData: {}", correlationData);
            } else {
                log.error("消息未到达Broker，原因：{}，correlationData: {}", cause, correlationData);
                // 可在此进行消息重发逻辑
            }
        });

// 发送带correlationData的消息（用于追踪）
        String correlationId = UUID.randomUUID().toString();
        CorrelationData correlationData = new CorrelationData(correlationId);
        // 显式设置消息属性
        MessageProperties messageProperties = new MessageProperties();
        messageProperties.setCorrelationId(correlationId);
        rabbitTemplate.convertAndSend("order.try.exchange", "order.try.create", new Message(JSON.toJSONString(order).getBytes() ,messageProperties), correlationData);


    }

    public void createOrder1(Order order) {
        log.info("接收到订单：{}", order);
        //版本2 添加确认监听
        // 生产者添加确认监听
        rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
            if (ack) {
                log.info("消息成功到达Broker，correlationData: {}", correlationData);
            } else {
                log.error("消息未到达Broker，原因：{}，correlationData: {}", cause, correlationData);
                // 可在此进行消息重发逻辑
            }
        });

// 发送带correlationData的消息（用于追踪）
        String correlationId = UUID.randomUUID().toString();
        CorrelationData correlationData = new CorrelationData(correlationId);
        // 显式设置消息属性
        MessageProperties messageProperties = new MessageProperties();
        messageProperties.setCorrelationId(correlationId);
        rabbitTemplate.convertAndSend("order.exchange", "order.create",new Message(JSON.toJSONString(order).getBytes() ,messageProperties), correlationData);


    }


    public void createMain1Order(Order order) {
        log.info("接收到订单：{}", order);
        //版本3 死信队列
        rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
            if (ack) {
                log.info("消息成功到达Broker，correlationData: {}", correlationData);
            } else {
                log.error("消息未到达Broker，原因：{}，correlationData: {}", cause, correlationData);
                // 可在此进行消息重发逻辑
            }
        });

// 发送带correlationData的消息（用于追踪）
// 发送带correlationData的消息（用于追踪）
        String correlationId = UUID.randomUUID().toString();
        CorrelationData correlationData = new CorrelationData(correlationId);
        // 显式设置消息属性
        MessageProperties messageProperties = new MessageProperties();
        messageProperties.setCorrelationId(correlationId);
        messageProperties.setExpiration("30000"); // 单位：毫秒
        rabbitTemplate.convertAndSend("order.main1.exchange", "order.main1.create", new Message(JSON.toJSONString(order).getBytes() ,messageProperties), correlationData);
    }



    public void createOrder2(Order order) {
        log.info("接收到订单：{}", order);
        //版本3 死信队列
        rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
            if (ack) {
                log.info("消息成功到达Broker，correlationData: {}", correlationData);
            } else {
                log.error("消息未到达Broker，原因：{}，correlationData: {}", cause, correlationData);
                // 可在此进行消息重发逻辑
            }
        });

// 发送带correlationData的消息（用于追踪）
// 发送带correlationData的消息（用于追踪）
        String correlationId = UUID.randomUUID().toString();
        CorrelationData correlationData = new CorrelationData(correlationId);
        // 显式设置消息属性
        MessageProperties messageProperties = new MessageProperties();
        messageProperties.setCorrelationId(correlationId);
        //设置消息持久化到磁盘
        messageProperties.setDeliveryMode(MessageDeliveryMode.PERSISTENT);

        rabbitTemplate.convertAndSend("order.main.exchange", "order.main.create", new Message(JSON.toJSONString(order).getBytes() ,messageProperties), correlationData);
    }

    /**
     * 发送延迟消息
     * @param order 订单对象
     * @param delaySeconds 延迟秒数
     */
    public void sendDelayMessage(Order order, int delaySeconds) {
        // 设置消息属性，包括 TTL
        MessageProperties messageProperties = new MessageProperties();
        messageProperties.setDelayLong(delaySeconds * 1000L);
        Message message = new Message(JSON.toJSONString(order).getBytes(), messageProperties);

        // 发送到延迟队列
        rabbitTemplate.send("order.delay.exchange", "order.delay", message);
        log.info("发送延迟消息，订单号：{}，延迟时间：{}秒", order.getId(), delaySeconds);
    }

    public void sendDelayMessage1(Order order, int delaySeconds) {
        // 设置消息属性，包括 TTL
        MessageProperties messageProperties = new MessageProperties();
        messageProperties.setExpiration(String.valueOf(delaySeconds * 1000));
        Message message = new Message(JSON.toJSONString(order).getBytes(), messageProperties);

        // 发送到延迟队列
        rabbitTemplate.send("order.delay1.exchange", "order.delay1", message);
        log.info("发送延迟消息，订单号：{}，延迟时间：{}秒", order.getId(), delaySeconds);
    }




    public void sendBatchMessage(Order order) {
        log.info("接收到订单：{}", order);
        for (int i = 0; i < 100; i++) {
            order.setUserId(i+"");
            Message message = new Message(JSON.toJSONString(order).getBytes());

            batchingRabbitTemplate.convertAndSend("order.batch.exchange", "order.batch", message);
        }
        log.info("send 100 messages, exchange: {}, payload: {}", "order.batch.exchange", order);

    }

    public void sendSequenceMessage(Order order) {
        log.info("接收到订单：{}", order);
        for (int i = 0; i < 100; i++) {
            order.setUserId(i+"");
            rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
                if (ack) {
                } else {
                    // 可在此进行消息重发逻辑
                }
            });

// 发送带correlationData的消息（用于追踪）
// 发送带correlationData的消息（用于追踪）
            String correlationId = UUID.randomUUID().toString();
            CorrelationData correlationData = new CorrelationData(correlationId);
            // 显式设置消息属性
            MessageProperties messageProperties = new MessageProperties();
            messageProperties.setCorrelationId(correlationId);
            //设置消息持久化到磁盘
            messageProperties.setDeliveryMode(MessageDeliveryMode.PERSISTENT);

            rabbitTemplate.convertAndSend("order.sequence.exchange", "order.sequence", new Message(JSON.toJSONString(order).getBytes() ,messageProperties), correlationData);


        }
        log.info("send 100 messages, exchange: {}, payload: {}", "order.sequence.exchange", order);
    }
}